<?php
/**
 * 使用PHP原生Socket接收TCP连接
 */

set_time_limit(0);
ob_implicit_flush(true);

echo "🔧 启动PHP Socket TCP服务器...\n";

// 创建Socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    die("❌ 创建Socket失败: " . socket_strerror(socket_last_error()) . "\n");
}

// 设置选项
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);

// 绑定地址和端口
if (!socket_bind($socket, '0.0.0.0', 2347)) {
    die("❌ 绑定地址失败: " . socket_strerror(socket_last_error($socket)) . "\n");
}

// 开始监听
if (!socket_listen($socket, 10)) {
    die("❌ 监听失败: " . socket_strerror(socket_last_error($socket)) . "\n");
}

echo "✅ Socket服务器启动成功\n";
echo "📍 监听地址: tcp://0.0.0.0:2347\n";

$clients = [];

while (true) {
    // 接受新连接
    $newClient = socket_accept($socket);
    if ($newClient !== false) {
        // 获取客户端信息
        socket_getpeername($newClient, $clientIp, $clientPort);
        $clientId = uniqid();
        
        echo "✅ 新的客户端连接: {$clientIp}:{$clientPort} [ID: {$clientId}]\n";
        
        // 保存客户端连接
        $clients[$clientId] = [
            'socket' => $newClient,
            'ip' => $clientIp,
            'port' => $clientPort,
            'connect_time' => time()
        ];
        
        // 发送欢迎消息
        $welcome = "Welcome to ThinkPHP Socket Server! Your ID: {$clientId}\n";
        socket_write($newClient, $welcome, strlen($welcome));
        
        // 创建子进程处理客户端（简单处理，生产环境建议用pcntl_fork）
        $this->handleClient($newClient, $clientId, $clientIp, $clientPort);
    }
    
    // 简单的清理断开连接（实际生产环境需要更复杂的连接管理）
    $this->cleanDisconnectedClients($clients);
    
    usleep(100000); // 100ms间隔
}

socket_close($socket);

/**
 * 处理客户端连接
 */
function handleClient($clientSocket, $clientId, $clientIp, $clientPort) {
    echo "🔧 开始处理客户端: {$clientIp}:{$clientPort}\n";
    
    while (true) {
        // 读取数据
        $data = socket_read($clientSocket, 1024);
        
        if ($data === false || $data === '') {
            // 连接断开
            echo "🔌 客户端断开连接: {$clientIp}:{$clientPort}\n";
            socket_close($clientSocket);
            break;
        }
        
        // 处理接收到的数据
        $data = trim($data);
        echo "📨 收到来自 {$clientIp} 的数据: {$data}\n";
        
        // 处理业务逻辑
        $response = $this->processRequest($data, $clientId);
        
        // 发送响应
        socket_write($clientSocket, $response . "\n", strlen($response) + 1);
    }
}

/**
 * 处理请求
 */
function processRequest($data, $clientId) {
    // 简单的命令处理
    switch ($data) {
        case 'time':
            return "Server time: " . date('Y-m-d H:i:s');
            
        case 'hello':
            return "Hello client {$clientId}!";
            
        case 'quit':
            return "Goodbye!";
            
        default:
            return "Unknown command: {$data}";
    }
}

/**
 * 清理断开连接的客户端
 */
function cleanDisconnectedClients(&$clients) {
    foreach ($clients as $clientId => $client) {
        // 简单的健康检查（实际需要更复杂的心跳检测）
        if (!is_resource($client['socket']) || @socket_write($client['socket'], '', 0) === false) {
            echo "🧹 清理断开连接的客户端: {$clientId}\n";
            unset($clients[$clientId]);
        }
    }
}